package com.reach.redis.interceptor;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.reach.redis.annotation.Cacheable;
import com.reach.redis.aspect.CacheAspect;
import com.reach.redis.bo.CacheConfig;
import com.reach.redis.factory.AbstractCacheFactory;
import com.reach.redis.manager.ManagerCache;
import com.reach.redis.manager.SpringContextUtil;
import com.reach.redis.utils.GsonUtils;

import net.sf.cglib.proxy.MethodProxy;
 
/**
 * 缓存拦截
 */
public class QueryCacheInterceptor extends AbstractCacheInterceptor  {
	
	private static final Logger logger = LoggerFactory.getLogger(AbstractCacheFactory.class);

	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		
		if(logger.isDebugEnabled()) {
			logger.debug("Cache intercept query  class [{}], method [{}],args [{}].",obj.getClass().getName(),method.getName(),String.valueOf(args));
		}
		
		CacheAspect cacheAspect = (CacheAspect) SpringContextUtil.getBean("cacheAspect");
		CacheConfig cacheConfig = ManagerCache.queryCacheMap.get(getClassName(obj.getClass().getName())+"."+method.getName());
		final String cacheKey = getFullKey(args,cacheConfig) ;
		Object cacheValue = cacheAspect.readCache(cacheKey);
		if(logger.isDebugEnabled()) {
			logger.debug("Cache intercept query  class [{}], method [{}],args [{}],value [{}].",obj.getClass().getName(),method.getName(),String.valueOf(args),GsonUtils.toString(cacheValue));
		}
		
		if(StringUtils.isEmpty(cacheValue)) {
			 Object result = proxy.invokeSuper(obj, args);
			cacheAspect.writeCache(result,cacheKey);
			return result;
		}
		return cacheValue;
	}

	@Override
	public String[] getAnnotation(CacheConfig cacheConfig) {
		return getCache(cacheConfig).key().split(",");
	}
	
	public Cacheable getCache(CacheConfig cacheConfig) {
		Cacheable cacheable = (Cacheable) cacheConfig.getCache();
		return cacheable;
	}

	@Override
	public String getModule(CacheConfig cacheConfig) {
		return getCache(cacheConfig).module();
	}

	@Override
	public String getEvent(CacheConfig cacheConfig) {
		return getCache(cacheConfig).event();
	}
 
}